跳到主要内容

分组 Group

Group 是一个有标题栏的带边框盒子。如果说 Panel 是隐形的 <div>,那 Group 就是醒目的 <fieldset>——它天生带有视觉分组能力,能让用户一眼看出"这一块内容是相关的"。

一句话理解

Group = Panel + 标题栏 + 边框。适合把相关的控件打包成一个视觉单元。


函数原型

bool BeginGroup(const HXString &Title, GroupProfile &Profile);
void EndGroup(GroupProfile &Profile);

参数说明

参数类型说明
Titleconst HXString &显示在分组顶部的标题文字。使用 HXStr("标题")L"标题"
ProfileGroupProfile &分组的配置结构体。必须是 static 或全局变量

返回值

类型说明
booltrue —— 分组可见且未折叠,继续往里面放控件。
false —— 分组被折叠或不可见,跳过内部绘制。

GroupProfile 结构体

字段类型默认值说明
SizeHXPoint{-1, -1}分组尺寸。{-1, -1} 表示自动根据内容计算。
PaddingHXGInt8内边距:边框到内部控件的距离。
MarginHXGInt5外边距:分组与外部其他控件的距离。
DirectionHXLayoutDirectionVertical内部布局方向。
ItemAlignHXLayoutAlignStretch子控件的对齐方式。
ClipContentboolfalse是否裁剪超出边界的内容。
TitleBarHeightint24标题栏高度(像素)。
FontSizeint20标题文字字体大小。
注意背景色和边框色

Group 的边框和标题栏颜色来自当前主题的 GroupBorderColorGroupTitleBackground,而不是像 Panel 那样由 Profile 直接指定。如果你需要自定义颜色,建议改用 Panel 手动实现。


基本用法

最简单的 Group,就是把一堆相关的控件包起来:

static HX::GroupProfile gp;

if (HX::BeginGroup(HXStr("音频设置"), gp)) {
HX::Slider1f(HXStr("主音量"), masterVol, sp);
HX::Slider1f(HXStr("背景音乐"), bgmVol, sp);
HX::Slider1f(HXStr("音效"), sfxVol, sp);
HX::EndGroup(gp);
}

与 Panel 的区别

特性PanelGroup
标题栏❌ 无✅ 有
边框样式手动设置 BorderColor自动使用主题样式
背景色手动设置 BackgroundColor自动使用主题样式
用途自由容器、卡片、布局隔离功能分组、设置项归类
视觉权重重(自带标题,更醒目)
怎么选?
  • 要做左侧导航栏、内容卡片、透明布局隔离 → Panel
  • 要做"音频设置"、"网络配置"、"外观选项"这种带标题的分组 → Group

嵌套使用

Group 可以嵌套 Group,Panel 和 Group 也可以互相嵌套。不过注意:嵌套太深会让 UI 显得臃肿,一般两到三层就够了。

static HX::GroupProfile outer;
static HX::GroupProfile inner;

if (HX::BeginGroup(HXStr("游戏设置"), outer)) {

HX::Text(HXStr("基础选项..."));

if (HX::BeginGroup(HXStr("画面"), inner)) {
HX::Slider1f(HXStr("分辨率缩放"), scale, sp);
HX::Checkbox(HXStr("全屏"), cp);
HX::EndGroup(inner);
}

if (HX::BeginGroup(HXStr("操控"), inner)) {
HX::Slider1f(HXStr("鼠标灵敏度"), sens, sp);
HX::Checkbox(HXStr("反转 Y 轴"), cp);
HX::EndGroup(inner);
}

HX::EndGroup(outer);
}

完整示例代码

#include <include/hex.h>
#include <include/impl/EasyX/hex_impl_easyx.h>

int main() {
initgraph(800, 600);
setbkcolor(WHITE);
cleardevice();

HX::HXInitForEasyX();
HX::SetBuffer(GetWorkingImage());

BeginBatchDraw();

static HX::WindowProfile wp;
wp.Size = {500, 500};

static float masterVol = 0.8f, bgmVol = 0.6f, sfxVol = 0.9f;
static HX::SliderProfile1f sp;
static HX::CheckboxProfile cp;

while (true) {
HX::HXBegin();

ExMessage msg;
while (peekmessage(&msg)) {
HX::PushMessage(HX::GetHXMessage(&msg));
}

HX::Window(HXStr("Group 演示"), wp);

// ---------- 音频设置组 ----------
static HX::GroupProfile audioGp;
if (HX::BeginGroup(HXStr("音频设置"), audioGp)) {
HX::Slider1f(HXStr("主音量"), masterVol, sp);
HX::Slider1f(HXStr("背景音乐"), bgmVol, sp);
HX::Slider1f(HXStr("音效"), sfxVol, sp);
HX::EndGroup(audioGp);
}

// ---------- 显示设置组 ----------
static HX::GroupProfile displayGp;
if (HX::BeginGroup(HXStr("显示设置"), displayGp)) {
HX::Checkbox(HXStr("全屏模式"), cp);
HX::Checkbox(HXStr("垂直同步"), cp);
HX::Checkbox(HXStr("显示 FPS"), cp);
HX::EndGroup(displayGp);
}

// ---------- 嵌套组 ----------
static HX::GroupProfile advancedGp;
if (HX::BeginGroup(HXStr("高级选项"), advancedGp)) {
HX::Text(HXStr("以下选项修改后需要重启游戏:"));

static HX::GroupProfile netGp;
if (HX::BeginGroup(HXStr("网络"), netGp)) {
HX::Checkbox(HXStr("使用 IPv6"), cp);
HX::Checkbox(HXStr("代理服务器"), cp);
HX::EndGroup(netGp);
}

HX::EndGroup(advancedGp);
}

HX::End();
HX::Render();
FlushBatchDraw();
Sleep(16);
}

closegraph();
return 0;
}
小建议

Group 的标题是用户快速扫描界面时的"路标"。起个好标题(如"音频设置"而不是"设置1")能显著提升界面的可读性。